package com.appkubes.portal.admin.application.auth.service.impl;

import com.appkubes.common.exception.BusinessException;
import com.appkubes.common.utils.UUIDUtils;
import com.appkubes.portal.admin.application.app.role.entity.vo.RoleAddVO;
import com.appkubes.portal.admin.application.auth.service.KeyCloakRoleService;
import com.appkubes.portal.admin.application.auth.service.KeyCloakService;
import lombok.extern.slf4j.Slf4j;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.RoleResource;
import org.keycloak.admin.client.resource.RoleScopeResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.representations.idm.RoleRepresentation;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class KeyCloakRoleServiceImpl implements KeyCloakRoleService {
    @Resource
    KeyCloakService keyCloakService;

    @Override
    public RoleRepresentation createClientRole(String roleName) {
        return createClientRole(roleName, "");
    }

    @Override
    public RoleRepresentation createClientRole(RoleAddVO roleAddVO) {
        return createClientRole(roleAddVO.getRoleCode(), roleAddVO.getRoleName());
    }

    public RoleRepresentation createClientRole(String roleName, String description) {
        ClientResource clientResource = keyCloakService.getClientResource();
        // 新建 client 角色
        RoleRepresentation clientRole = new RoleRepresentation();
        clientRole.setName(roleName);
        clientRole.setId(UUIDUtils.getUUID());
        clientRole.setDescription(description);
        clientRole.setClientRole(true);
        clientResource.roles().create(clientRole);
        return clientRole;
    }


    @Override
    public RoleRepresentation getClientRole(String roleName) {
        ClientResource clientResource = keyCloakService.getClientResource();
        RoleResource roleResource = clientResource.roles().get(roleName);
        return roleResource.toRepresentation();
    }

    @Override
    public Boolean deleteClientRole(String clientRoleName) {
        ClientResource clientResource = keyCloakService.getClientResource();
        clientResource.roles().deleteRole(clientRoleName);
        return true;
    }

    @Override
    public List<RoleRepresentation> getClientRoleList() {
        List<RoleRepresentation> clientRoles = keyCloakService.getClientResource().roles().list();
        return clientRoles;
    }

    @Override
    public List<RoleRepresentation> getUserClientRoleList(String userId) {
        List<RoleRepresentation> roleList = getUserClientRoles(userId).listAll();
        return roleList;
    }

    @Override
    public RoleRepresentation getUserClientRole(String userId, String roleName) {
        RoleResource roleResource = keyCloakService.getClientResource().roles().get(roleName);
        return roleResource.toRepresentation();
    }

    @Override
    public void addRoleToUser(String userId, String roleName) {
        RoleScopeResource roleScopeResource = getUserClientRoles(userId);
        RoleRepresentation roleRepresentation = getUserClientRole(userId, roleName);
        if (roleRepresentation == null) {
            throw new BusinessException("找不到客户端角色");
        }
        List<RoleRepresentation> toAdd = new ArrayList<>();
        toAdd.add(roleRepresentation);
        roleScopeResource.add(toAdd);
    }

    @Override
    public void removeRoleFromUser(String userId, String roleName) {
        RoleScopeResource roleScopeResource = getUserClientRoles(userId);
        RoleRepresentation roleRepresentation = getUserClientRole(userId, roleName);
        if (roleRepresentation == null) {
            throw new BusinessException("找不到客户端角色");
        }
        List<RoleRepresentation> toAdd = new ArrayList<>();
        toAdd.add(roleRepresentation);
        roleScopeResource.remove(toAdd);
    }

    RoleScopeResource getUserClientRoles(String userId) {
        UserResource userResource = keyCloakService.getUserResource(userId);
        ClientResource clientResource = keyCloakService.getClientResource();
        return userResource.roles().clientLevel(clientResource.toRepresentation().getId());
    }

}
